/**
 * Class: DVertex
 *
 * Purpose: 
 *
 * Created: Feb 21, 2010 @ 2:08:42 PM
 * @author Ken
 */
package org.openfantasia.util.math.geometry;

import org.openfantasia.util.math.DPoint3;

import java.util.ArrayList;
import java.util.List;

public class DVertex {

	private DMesh parent;

	private DPoint3 position;

	private String id;

	private List<DVertex> neighbors = new ArrayList<DVertex>();


	public DVertex() {
	}


	public DVertex(DMesh parent) {
		this.parent = parent;
	}


	public DVertex(DMesh parent, String id) {
		this.parent = parent;
		this.id = id;
	}


	public DVertex(DMesh parent, DPoint3 position) {
		this.parent = parent;
		this.position = position;
	}


	public DVertex(DMesh parent, DPoint3 position, String id) {
		this.parent = parent;
		this.position = position;
		this.id = id;
	}


	public static String defaultId(double x, double y, double z) {
		return x + ":" + y + ":" + z;
	}


	public DMesh getParent() {
		return parent;
	}


	public void setParent(DMesh parent) {
		this.parent = parent;
	}


	public DPoint3 getPosition() {
		return position;
	}


	public void setPosition(DPoint3 position) {
		this.position = position;
	}


	public String getId() {
		if (id == null) {
			return defaultId(position.getX(), position.getY(), position.getZ());
		}
		return id;
	}


	public void setId(String id) {
		this.id = id;
	}


	public List<DVertex> getNeighbors() {
		return neighbors;
	}


	public void addNeighbor(DVertex vertex) {
		if (!neighbors.contains(vertex)) {
			neighbors.add(vertex);
		}
	}


	public void removeNeighbor(DVertex vertex) {
		neighbors.remove(vertex);
	}


	public boolean isNeighborOf(DVertex vertex) {
		return neighbors.contains(vertex);
	}


	public List<DPolygon> getPolygons() {
		List<DPolygon> result = new ArrayList<DPolygon>();
		for (DVertex n : neighbors) {
			for (DVertex na : n.neighbors) {
				if ((na != this) && na.isNeighborOf(this)) {
					DEdge a = new DEdge(this.position.copy(), n.position.copy());
					DEdge b = new DEdge(n.position.copy(), na.position.copy());
					DEdge c = new DEdge(na.position.copy(), this.position.copy());
					DPolygon polygon = new DPolygon(a, b, c);
					if (!result.contains(polygon)) {
						result.add(polygon);
					}
				}
			}
		}
		return result;
	}


	@Override
	public boolean equals(Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof DVertex)) {
			return false;
		}

		DVertex dVertex = (DVertex) o;

		if (id != null ? !id.equals(dVertex.id) : dVertex.id != null) {
			return false;
		}
		if (neighbors != null ? !neighbors.equals(dVertex.neighbors) : dVertex.neighbors != null) {
			return false;
		}
		if (parent != null ? !parent.equals(dVertex.parent) : dVertex.parent != null) {
			return false;
		}
		if (position != null ? !position.equals(dVertex.position) : dVertex.position != null) {
			return false;
		}

		return true;
	}


	@Override
	public int hashCode() {
		int result = parent != null ? parent.hashCode() : 0;
		result = 31 * result + (position != null ? position.hashCode() : 0);
		result = 31 * result + (id != null ? id.hashCode() : 0);
		result = 31 * result + (neighbors != null ? neighbors.hashCode() : 0);
		return result;
	}
}
